package com.duguo.dynamicmvc.factory.processor.model;

import java.util.Map;

import javassist.CtClass;
import javassist.CtPrimitiveType;

import com.duguo.dynamicmvc.factory.utils.BeanUtils;
import com.duguo.dynamicmvc.factory.utils.javassist.MethodUtils;

public class ModelMethodCreatorImpl implements ModelMethodCreator{
	

	public void overrideModelMethod(CtClass modelImplCtClass, Map<String, CtClass> fields) throws Exception {
		if(fields.size()>0){
            overrideModelPut(modelImplCtClass,fields);
            overrideModelRemove(modelImplCtClass,fields);
            overrideModelClear(modelImplCtClass,fields);
        }
	}

    private void overrideModelPut(CtClass modelImplCtClass, Map<String,CtClass> fields)throws Exception {
        StringBuffer methodBody = new StringBuffer("public Object put(Object key, Object value) {");
        for(String fieldName:fields.keySet()){
            methodBody.append("if(\""+fieldName+"\".equals(key)){");
			if(fields.get(fieldName).isPrimitive()){
				CtPrimitiveType fieldType=(CtPrimitiveType)fields.get(fieldName);
				methodBody.append("if(value == null ){");
	            methodBody.append("Object defaultValue=getClass().newInstance();");
	            methodBody.append("this."+fieldName+"=(("+fieldType.getWrapperName()+")"+BeanUtils.class.getName()+".getFieldValue(defaultValue, \""+fieldName+"\", Object.class))."+fieldType.getGetMethodName()+"();");
		        methodBody.append("return super.remove(key);");
	            methodBody.append("}else{");
				methodBody.append("this."+fieldName+"=(("+fieldType.getWrapperName()+")value)."+fieldType.getGetMethodName()+"();");
	            methodBody.append("}");
		    }else{
			    methodBody.append("this."+fieldName+"= ("+fields.get(fieldName).getName()+")value ;");
				methodBody.append("if(value == null ){");
				methodBody.append("return super.remove(key);");
	            methodBody.append("}");
			}
            methodBody.append("}");
        }
        methodBody.append("return super.put(key,value);");
        methodBody.append("}");
        MethodUtils.addMethod(modelImplCtClass, methodBody.toString());
    }

    private void overrideModelRemove(CtClass modelImplCtClass, Map<String,CtClass> fields)throws Exception {
        StringBuffer methodBody = new StringBuffer("public Object remove(Object key) {");
        for(String fieldName:fields.keySet()){
            methodBody.append("if(\""+fieldName+"\".equals(key)){");
            methodBody.append("return put(\""+fieldName+"\",null);}");
        }
        methodBody.append("return super.remove(key);");
        methodBody.append("}");
        MethodUtils.addMethod(modelImplCtClass, methodBody.toString());
    }

    private void overrideModelClear(CtClass modelImplCtClass, Map<String,CtClass> fields)throws Exception {
        StringBuffer methodBody = new StringBuffer("public void clear(){");
        for(String fieldName:fields.keySet()){
        	methodBody.append("remove(\""+fieldName+"\");");
        }
        methodBody.append("super.clear();");
        methodBody.append("}");
        MethodUtils.addMethod(modelImplCtClass, methodBody.toString());
    }

}
